B11【动态路由】ospf详解
前言
OSPF开放式最短路径优先(Open Shortest Path First)是IETF组织开发的一个基于链路状态的内部网关协议。本文将介绍的是OSPF v2版本。除此之外还有一个v3版本,其适用于IPv6环境。
上一篇我们讲过的RIP是基于距离矢量算法的路由协议,存在着收敛慢、路由环路、可扩展性差等问题。
OSPF作为基于链路状态的协议,能够解决RIP所面临的诸多问题,目前RIP正在被OSPF淘汰。
- 以运行RIP为例的距离矢量路由协议的路由器是依靠周期性的泛洪自己的路由表,每台路由器都从相邻路由器学习路由,它们不清楚网络的拓扑结构,只是简单的知道前往某个网段应该从那里走,走多远(出接口是哪、跳数多少)。
- 而运行以OSPF为例的链路状态路由协议的路由器则清楚整个网络拓扑结构,并以此计算规划出路线,从而使得路由不易环路。它们之间会先建立邻居关系,再交换链路状态信息,它们并不交换路由信息。路由信息只由自己收集链路状态信息后计算得到。
与其说让OSPF与RIP作比较来进行学习,我认为借助STP的知识来学习会更得心应手。不过一开始还是先跟RIP比较一下,之后介绍原理的时候我们就可以试着跟STP的原理对比一下。
因此,在介绍OSPF之前,我们就得清楚什么是链路状态。
链路状态
链路状态路由协议则是使用一些特殊的信息描述网络的拓扑结构与网段信息,这些信息称为链路状态信息(Link State)。
这些信息会被存放于链路状态数据库LSDB(Link State Database)中,LSDB可以被视为对整个网络拓扑结构以及网段信息的描绘,LSDB同步后,所有路由器拥有对网络的一致认知。
接下来路由器都会独立进行SPF(shortest path first)最短路径优先算法,以得到一颗无环的最短路径树。
这棵树以自己为根,并且可以到达网络的各个角落,最终路由器将基于这棵树产生路由,并加载到路由表中。
在OSPF中,这些链路状态信息被称为LSA(Link-State Advertisement,链路状态通告),OSPF定义了多种LSA类型,我们后续会介绍学习每种LSA的用途。
一般来说,我们可以认为一台路由器a发送给路由器b的LSA中包含了网段,发现该网段的路由器,到达该目标网段的接口IP。
似乎一时间无法理解这与rip协议这种距离矢量协议直接传递的路由有什么不同。
解释一下,“ 发现该网段的路由器 ” 不一定是路由器a,可以是其他路由器,在rip中是没有这个信息。
而”到达该目标网段的接口IP“ 则是路由器a与路由器b相连的接口的IP,这与rip中传递的路由信息的下一跳是一个意思。
实际lsa中不止包含以上三个信息,还有其他信息,这些信息集合起来就为路由器描绘整个网络结构提供了充分条件。
ospf的基础原理
我们先粗略的过一遍ospf的原理,再不断扩宽框架,有一个完整框架之后再由浅入深。
OSPF适用于多种网络类型中(点对点、点对多点、多点对多点),本文未做特别说明的情况下,默认为介绍在多点对多点的网络(常见的以太网)下的情景。
原理简述
OSPF 的工作原理简述:
邻居发现:OSPF 路由器通过发送 Hello 报文来发现相邻的路由器。当两台路由器在相互发送 Hello 报文确认彼此可达时,它们就成为邻居。
链路状态广播:一旦建立邻居关系,路由器将定期发送链路状态更新报文(LSU),其中包含本地路由器所知道的网络拓扑信息(LSA)。
路由计算:收到 LSU 报文后,每台路由器将更新其链路状态数据库(LSDB),并使用 Dijkstra 算法计算出最短路径树(SPF Tree),确定到达目的网络的最佳路径。
路由表生成:根据 SPF Tree 计算结果,每台路由器生成自己的路由表,记录到达各个目的网络的最佳路径和下一跳信息。
路由更新:如果网络拓扑发生变化,比如链路断开或恢复,路由器将重新计算最短路径树,并将这些链路状态信息的更新通过 LSU 报文广播给相邻路由器,以便网络中的所有路由器都能及时了解变化。
上述提到的广播并不是真正严格意义上的广播(目标地址全1),OSPF是通过组播的方式进行通信的。
DR、router-id
但如果每两台路由器都进行完整的LSA传递(包括后续的定期报文与更新报文),那么对网络资源是不小的占用。为此,OSPF中引入了类似于STP根桥的主备机制;同时为了标识路由器,也引入了类似于STP桥id的概念。
- OSPF定义了指定路由器DR和备份指定路由器BDR。
通过选举产生DR(Designated Router)后,所有路由器都只将信息发送给DR,由DR将网络链路状态LSA广播出去。如果DR由于某种故障而失效,则网络中的路由器必须重新选举DR,并与新的DR同步。这需要较长的时间,在这段时间内,路由的计算有可能是不正确的。
为了能够缩短这个过程,OSPF提出了BDR(Backup Designated Router)的概念。BDR是对DR的一个备份,在选举DR的同时也选举出BDR。当DR失效后,BDR会立即成为DR。由于不需要重新选举,并且关系已建立,所以这个过程非常短暂,这时还需要再重新选举出一个新的BDR,虽然一样需要较长的时间,但此时已经有新DR在工作了,并不会影响网络通信。
- OSPF定义了Router-ID (Router Identification,路由器标识)。
router-id是一个32bit长度的数值,通常使用点分十进制表示(与IPv4地址一样),用于一个OSPF区域内表示唯一的一台路由器。也就是说router-id不能重复,冲突会导致无法建立关系。
一般router-id会自动根据路由器已配置的ip地址选定;但由于router-id不能重复,且与STP中的桥id类似,会影响根的选举,所以推荐手动配置router-id。
- OSPF中DR/BDR的选举规则
STP选举根桥的规则是先比较优先级值,优先级值一样,再比较mac。
OSPF与之类似,也是先比较优先级值,不过后比较的不是mac值而是router-id。
当处于同一网段的两台路由器同时宣布自己是DR时,DR优先级高者胜出。
如果优先级相等,则Router ID大者胜出。如果一台路由器的优先级为0,则它不会被选举为DR或BDR。
- DR的选举不具备抢占性,当网络中有设备已经是DR的情况下,新接入的设备即便优先级更高,也还是认之前的DR路由器。
报文发送方式
OSPF协议报文封装于IP协议报文中,协议号89。OSPF常使用两个组播地址进行数据通信。(目的地址)
- 224.0.0.5:该组播地址指向所有OSPF路由器。
- 224.0.0.6:该组播地址指向DR/BDR路由器。
举个例子,在OSPF关系稳定后,普通OSPF路由器向DR发布链路更新报文使用224.0.0.6地址,而DR周期性的向所有路由发布定期报文或更新报文就采用224.0.0.5的地址
不使用广播地址的原因就是为了不影响其他的非OSPF设备。而不使用同一个组播地址的原因则是为了上一节说的DR机制。
注意,因为OSPF是使用组播地址进行通信,组播地址也可以算作一种广播,是会被网段隔离的,无法跨网段传输。因此选举DR与BDR,只能在一个网段内进行。
因此,在OSPF中,每个网段都会选举DR/BDR,也就是说总体上看,可能会出现多个DR。
邻居与邻接关系
我们一般会根据是否发送后续LSA更新来判断两台OSPF路由器是处于邻居还是邻接关系。
邻居关系是指两台路由器之间都能基于OSPF进行通信,也就是都拥有对方的信息(router-id)
而邻接关系是值两台路由器之间会进行LSA的交换并且LSDB最终都保持相同。
一般一个OSPF区域中,所有路由器两两之间都处于邻居关系;与DR以及BDR之间则处于邻接关系。
事实上,也正是设定了DR、BDR的机制后才有了邻居与邻接的区分,否则邻居关系只是一个过程罢了。
邻居表
一个路由器的接口激活OSPF后,该接口将会周期性的发送OSPF hello报文。
当OSPF接口收到hello报文,也就是发现邻居后,该hello报文中的信息将会被写入到路由器的OSPF邻居表中。
在邻居表中我们就可以看到“邻居”是处于邻居关系还是邻接关系。
有关hello报文的内容稍后介绍。
OSPF域
现在我们知道OSPF至少会维护三张数据表,分别是存放LSA信息的LSDB表、存放邻居信息的邻居表、存放计算得到的路由信息的路由表。
如果一个OSPF进程中存在十几台路由器、上百个网段,基于LSDB必须全路由器同步的机制,那么每台路由器维护的LSDB表将会很大,而根据LSDB计算而来的路由表也小不了。如果路由器数量更多,那么会更加庞大,同步这些表信息则会占用大量的网络资源,根据如此庞大的表信息进行计算也会消耗大量的设备性能。
因此,OSPF引入了区域的概念(Area),每个区域内部维护自己LSDB表,LSA的泛洪限制在区域内,避免对区域外部造成影响。
处于区域之间的路由器则额外负责进行LSA的整合,为连接的两个区域发布聚合的信息,以保证两个区域之间仍可进行通信。
但为了避免路由环路,所以设立了骨干区域(中心区域),只有一侧处于骨干区域的路由器 才拥有发布跨区域LSA的权限。
因此,每个区域都必须与骨干区域相连,否则没有一侧处于骨干区域的路由器 的帮助,缺少其他区域的LSA信息,则该区域无法与外界通信,成为一座“孤岛”。
似乎有点抽象,我们比喻一下。
让快递小哥记忆全国所有城市的街道信息、楼栋信息这很难。
实际快递小哥只需要知道他负责区域的详细地理信息即可,超过他负责范围的快递件,他就拿回站点。
该快递件由站点直接发送给本市的分拣中心,在这里被发到转运中心。
由转运中心发往目标城市的分拣中心,最后再通过该城市的站点与快递小哥送达收件人手中。
区域的格式
Area-id与router-id一样,也是32bit的按点分十进制表示的数,例如:area0.0.0.1。
但实际上我们更常用完全的十进制来表示,例如area0.0.0.1写为area1,area0.0.1.0写为area256。
骨干区域为area0.0.0.0也就是area0。
Tips
DR和BDR的选举是在每个OSPF区域上进行的,而不是在整个OSPF进程中进行的。这意味着在一个OSPF进程中可能存在多个DR和BDR。
OSPF路由器的角色
了解了以上的各种概念后,我们就可以来介绍一下OSPF中路由器一共有哪些角色。(除开表示根的DR与BDR)
虽然会叫某某OSPF路由器,但请记住所有的协议进程都是以接口为主来运行的。
内部路由器(Internal Router,IR):所有接口都接入同一个OSPF区域的路由器。
区域边界路由器(Area Border Router,ABR):接入多个区域的路由器且至少一个接口在Area0中激活的路由器。ABR负责在区域之间传递路由信息,因此ABR必须连接到Area0,并同时连接着其他区域。
骨干路由器(Backbone Router,BR):接入Area0的路由器。ABR也是骨干路由器。
AS边界路由器 (AS Boundary Router,ASBR):ASBR将OSPF域外的路由引入本域,使得外部路由在整个OSPF 域内传递。
比如说一台路由器除了接入OSPF网络,它还接入了一个RIP网络,如果它将自己路由表中通过RIP学习到的路由重分发到了OSPF 中,那它就是ASBR。(是先干了这事,它才成为ASBR)
并不是同时运行多种路由协议的OSPF路由器就一定是ASBR,ASBR一定是将外部路由重分发到OSPF,或者执行了路由重分发操作的路由器。
虽然BR、ABR、ASBR这三者看起来都带了“BR”的名头,但它们并不是同一个意思。(所以标注了英文全称)
实际IR并没有什么特别的用途,只需记忆其他三个角色即可。
LSA类型1-5
正因为OSPF划分了区域,并设计了ABR与ASBR的机制,因此我们可以为各路由器间发布的LSA进行一个分类。(实际后续还有其他类型,我们由浅到深慢慢展开介绍。)
我们一般直接使用“类型几”这个称呼,几乎不使用完整的全称。
LSA类型 | LSA作用 |
---|---|
Router-LSA(Type1) | 每个设备都会产生,描述了设备的链路状态和开销,在所属的区域内传播。 |
Network-LSA(Type2) | 由DR产生,描述本网段的链路状态,在所属的区域内传播。(相当于DR对区域内所有路由器信息的汇总) |
Network-summary-LSA(Type3) | 由ABR产生,描述区域内某个网段的路由,并通告给其他区域。 |
ASBR-summary-LSA(Type4) | 由ABR产生,描述到ASBR的路由,通告给除ASBR所在区域的其他相关区域。 |
AS-external-LSA(Type5) | 由ASBR产生,描述到AS外部的路由,通告到所有的区域。 |
type-4也就是对于type-5的补充与售后,其他区域的路由器即便知道了到达ospf区域外的网段要通过ASBR,但它们不知道如何到达ASBR,就需要与ASBR同区域的ABR去传播到达该ASBR的路由信息。
小结
我们目前是粗略的过一遍基础概念原理,还不够理解的,不必在意,稍后会详细介绍。
总的来说:
- OSPF会进行区域划分,有一个骨干区域Area0,其他区域必须与骨干区域相连。
- OSPF中会对每台路由器分配一个router-id用于标识路由器身份。
- 每个区域内会基于router-id选举DR负责对区域内LSA的统合更新。
- 区域内的路由器通过类型1与类型2的LSA完成区域内LSDB的同步。
- 骨干区域与区域之间通过ABR的类型3LSA进行跨区域的信息传递。
- 如果某一台路由器连接了其他网络,并将该网络的路由信息引入到OSPF中,它会发布类型5的LSA告知其他路由器,同时它就宣布自己是一台ASBR。(全体目光向我看齐,我宣布个事,我是ASBR,去这个外部网络就来找我嗷。)
- 与该路由器同处一区域的ABR会自行产生并传播一条类型4的LSA用于告知其他路由器如何到达这台ASBR。
除此之外,OSPF还有其他还没有提到的知识点,我们稍后会以有什么需求,因此有什么解决方案的方式来一一展开讲解。
OSPF的报文格式、邻居状态、邻居/邻接建立过程
OSPF的报文类型
报文类型 | 报文作用 |
---|---|
Hello报文 | 周期性发送,用来发现和维持OSPF邻居关系。 |
DD报文(Database Description packet) | 描述本地LSDB(Link State Database)的摘要信息,用于两台设备进行数据库同步。 |
LSR报文(Link State Request packet) | 用于向对方请求所需的LSA。设备只有在OSPF邻居双方成功交换DD报文后才会向对方发出LSR报文。 |
LSU报文(Link State Update packet) | 用于向对方发送其所需要的LSA。 |
LSAck报文(Link State Acknowledgment packet) | 用来对收到的LSA进行确认。 |
LSA是链路状态信息,是报文内部的信息,注意不要混淆了名称。
OSPF的邻居状态
OSPF的邻居共有8种状态,分别是:Down、Attempt、Init、2-way、Exstart、Exchange、Loading、Full。
- Down:邻居会话的初始阶段,或者是没有在邻居失效时间间隔内收到来自邻居路由器的Hello数据包。
- Attempt:该状态仅发生在非广播的多路网络中(帧中继那一类,但基本被淘汰了),表明对端在邻居失效时间间隔(dead interval)超时前仍然没有回复Hello报文。此时路由器依然每发送轮询Hello报文的时间间隔(poll interval)向对端发送Hello报文。
- Init:收到Hello报文后状态为Init。
- 2-way:收到的Hello报文中包含有自己的Router ID,则状态为2-way;如果不需要形成邻接关系则邻居状态机就停留在此状态,否则进入Exstart状态。
- Exstart:开始协商主从关系,并确定DD的序列号,此时状态为Exstart。
- Exchange:主从关系协商完毕后开始交换DD报文,此时状态为Exchange。
- Loading:DD报文交换完成即Exchange done,此时状态为Loading。
- Full:LSR重传列表为空,此时状态为Full。full也表示邻接关系建立完毕。
建立邻居关系
如图所示为路由器R1与路由器R2的邻居关系建立过程。其中路由器R1的router-id为1.1.1.1,路由器R2的router-id为2.2.2.2。

R1的一个连接到广播类型网络的接口上激活了OSPF协议,并发送了一个Hello报文(目的地址使用组播地址224.0.0.5;源地址为接口IP:10.1.12.1)
同时该报文内包含了router-id(指代发送人),区域id,网络掩码(与源ip结合起来得到该接口的网段),OSPF的一些定时器,以及最重要的已发现邻居列表。(当前未发现,则为空)。
R2收到R1发送的Hello报文后,学习到R1的router-id,计入进邻居表中,同时对外发布hello报文,并且在报文中的Neighbors Seen字段中填入R1的Router ID(Neighbors Seen=1.1.1.1),表示我知道有你这个邻居了,然后R2邻居状态机置为Init。
当R1收到R2回应的Hello报文,因报文内的邻居列表有自己的router-id,于是将邻居状态机置为2-way状态,同时也因为学习到了R2的id,会对外再发送一个更新的hello报文。
R2收到R1发送的最新Hello报文后,在报文内也发现了自己router-id,也将邻居状态机置为2-way状态
总结一下:收到hello报文,报文内没有自己的router-id,则状态为int;收到hello报文,报文内有自己的router-id,则状态为2-way。
这两个状态并不是连续的,上图中,RouterA的状态就是从Dowm直接过渡到2-way。
除开router-id,hello报文内的其他信息是构建邻居关系的重要条件;区域id、网段(源ip与掩码计算得出)、hello间隔、失效间隔哪怕有一项不相同,也无法构建邻居关系。
另外,当两台路由器构建完毕邻居关系(都标记为“2-way”状态),将会开始DR/BDR的选举。
建立邻接关系
当路由器确定好DR/BDR后,如果两台路由器之间都是非DR/BDR,则关系停留在邻居。
如果其中一台路由器为DR/BDR,则会交换LSA信息,最终发展为邻接关系。
此过程是以单播的形式进行交互,不采用OSPF默认的组播地址。
在交换LSA之前,路由器之间会协商主/从关系,然后先交换简要的LSA信息,待确定需要LSA信息后,会请求对方给出该简要信息的全部完整信息。
为了提高发送的效率,R1和R2首先了解对端数据库中哪些LSA是需要更新的,如果某一条LSA在LSDB中已经存在,就不再需要请求更新了。
为了达到这个目的,R1和R2先发送DD报文,DD报文中包含了对LSDB中LSA的摘要描述(每一条摘要可以唯一标识一条LSA)。
为了保证在传输的过程中报文传输的可靠性,在DD报文的发送过程中需要确定双方的主从关系,作为Master的一方定义一个序列号Seq,每发送一个新的DD报文将Seq加一,作为Slave的一方,每次发送DD报文时使用接收到的上一个Master的DD报文中的Seq。(类似TCP的机制)

R1首先发送一个DD报文,宣称自己是Master(MS=1),并规定序列号Seq=X(图中假定为200).
I=1表示这是第一个的DD报文,报文中并不包含LSA的摘要,只是为了协商主从关系。
M=1说明这不是最后一个报文,后续还有DD报文要发送。
R2在收到R1的DD报文后,将R1的邻居状态机改为Exstart,并且回应了一个DD报文(该报文中同样不包含LSA的摘要信息)。
由于R2的router-id较大,所以在报文中R2认为自己是Master,并且重新规定了序列号Seq=Y(图中假定为300)。
R1收到报文后,同意了R2为Master,并将R2的邻居状态机改为Exchange。
R1使用R2的序列号Seq=300来发送新的DD报文,该报文开始正式地传送LSA的摘要。
在报文中R1将MS=0,说明自己是Slave。
R2收到报文后,将R1的邻居状态机改为Exchange,并发送新的DD报文开始描述自己的LSA摘要,此时R2将报文的序列号改为Seq=300+1。
如果双方的LSDB包含的LSA信息数量很多,一条DD报文无法简述完毕,则会重复以上的交互,即:master路由器R2将DD序列号逐次加一,发送新的DD报文;slave路由器R1则使用前者的DD序列号发送自己的DD报文。

当R1将把自己的LSA摘要 都发送完毕,也就是发送最后一个DD报文时,会将M比特位设置位0,表示这是最后一个DD报文。
R2收到R1的最后一个DD报文的时候,恰好也是要发送最后一个报文了,同样将M比特位设置位0。
R1收到R2的最后一个序列号为309 的DD报文后,即便它已经没有LSA摘要 需要发布了,但它仍需要对R2的报文进行回复确认(DD序列号相同即为确认),则它会向R2发送一个空的序号为309的DD报文。
R1发送完毕DD报文且收到R2的最后一个DD报文后,就会开始查看R2的LSA摘要,R1发现其中有许多LSA是自己没有的,将邻居状态机改为Loading状态。
R1发送LSR报文向R2请求更新LSA。
R2用LSU报文来回应R1的请求。
同样的,如果R2需要向R1请求LSA,也会发送LSR报文。
R1收到R2的LSU报文后,发送LSAck报文确认。收到R2的LSR请求则发送LSU报文。
上述过程持续到R1/R2发现已经没有LSA需要向对方请求,同时R1/R2会将邻居状态机改为Full状态。
当R1与R2都将对方设置为Full状态,此时邻接关系建立完成。
OSPF的度量值——cost
每种路由协议对度量值的规定是不同的,RIP是采用跳数,而在OSPF中,是使用cost(开销、代价)作为路由度量值。
cost值越小,则路由越优,其含义是走该路由所需的开销/代价/成本最低。
这个东西与STP协议中计算到根桥的路径开销值是差不多的概念。
在STP里,链路开销是按链路带宽给一个固定值。
而在ospf里,链路开销cost是用一个带宽参考值除以链路带宽得到的,如果值小于1则计为1。
为了让路由器能分清千兆、万兆的链路,所以会将带宽参考值设置的大一些,以避免千兆与万兆的cost值计算出来都为1。
特殊区域(末梢区域)
ospf使用了区域的划分来限制LSA在网络中的泛洪,减小路由器内部表的规模,但我们还可以更进一步。
Stub Area (末梢区域)
当一个非area0的普通区域只有一个出口(也就是只有一个ABR),那么该区域就可以被配置为Stub区域。
当一个区域被配置为Stub区域,这个区域的ABR会拦截type-5 LSA(指向外部网络的路由)。同时,该ABR会以type-3 LSA的形式发布一条默认路由,让区域内路由器学习。
当然,发布的还是LSA,只是该LSA内的信息会被计算为默认路由。
另外既然拦截了type-5,那么type-4也没有存在意义,因此也会一并拦截。
也就是说,这台ABR作为唯一出口,那么其他路由器访问外部网络直接默认指向它就可以,不需要拥有指定网段的路由,反正最后也是要经过它。这样就缩小了LSA与路由表项模。
Totally Stub Area(完全末梢区域)
在stub区域的基础上,因为只有一个出口,那么我们很简单就可以想到,包括前往其他区域的路由也都是经过这个出口,那么也可以在本区域取消到其他区域的信息。
为此就提出了完全末梢区域,该区域的ABR会将区域路由也一并拦截,只发布一条type-3LSA——描述指向自己的默认路由给区域内的路由器。
这样一来,该区域内仅存在type-1与type-2、以及唯一一条type-3的LSA。
NSSA (Not-So-Stubby Area,非完全末梢区域)
不管是普通的Stub区域还是Totally Stub区域,都是会拦截type-4与type-5的LSA。
但假设该末梢区域内某台路由直接连接着一个外部网络(比如RIP网络),那么与该路由器同属于一个ospf网络的其他区域路由器就无法学习到该外部RIP网络,因为相关的LSA被拦截了。
如果要传递出去,那只能取消了末梢区域,可我们又想保留限制其他区域传来外部路由,有没有什么办法呢。
NSSA,非完全末梢区域就是为了解决这种情况出现的。
在NSSA中,启用了一种新的LSA类型,type-7:NSSA LSA。该类型LSA由ASBR产生,描述到AS外部的路由,仅在NSSA区域内传播。
而该区域的ABR会将该type-7LSA转化为type-5LSA再发送给其他区域,以便该描述外部路由的链路信息能在整个OSPF网络中通告。
Totally NSSA
NSSA对标的是普通Stub区域,其并不拦截type-3LSA。如果需要像Totally Stub区域一样,拦截type-3LSA,就可以配置为Totally NSSA区域。
小结
区域与其可允许出现的LSA类型:
type-1 | type-2 | type-3 | type-4 | type-5 | type-7 | |
---|---|---|---|---|---|---|
常规区域 | √ | √ | √ | √ | √ | × |
Stub区域 | √ | √ | √ | × | × | × |
Totally Stub区域 | √ | √ | × | × | × | × |
NSSA | √ | √ | √ | × | × | √ |
Totally NSSA | √ | √ | × | × | × | √ |
两个Totally区域禁用type-3区域后,会由ABR发布一条type-3的描述指向自己的默认路由的LSA。全区域内仅存在这一条type-3LSA信息。
OSPF的维护
一般来说,OSPF中的路由器会周期性的发布hello报文以及时发现邻居以及表示自身还存活着。
当路由器在规定的失效时间内还没有收到邻居的周期性hello报文,则会认为邻居挂了。(失效时间能在hello报文中查看)
当路由器会在发现网络拓扑发生变更时,像RIPv2那样触发更新,发布LSU报文给DR,以便网络更快地收敛。
LSA详解
先简单过一遍各种类型的名称与作用:
LSA类型 | LSA作用 |
---|---|
Router-LSA(Type1) | 每个设备都会产生,描述了设备的链路状态和开销,在所属的区域内传播。 |
Network-LSA(Type2) | 由DR产生,描述本网段的链路状态,在所属的区域内传播。(相当于DR对区域内所有路由器信息的汇总) |
Network-summary-LSA(Type3) | 由ABR产生,描述区域内某个网段的路由,并通告给其他区域。 |
ASBR-summary-LSA(Type4) | 由ABR产生,描述到ASBR的路由,通告给除ASBR所在区域的其他相关区域。 |
AS-external-LSA(Type5) | 由ASBR产生,描述到AS外部的路由,通告到所有的区域。 |
NSSA-LSA(Type7) | 仅用于NSSA区域,由该区域的ASBR产生,用于描述到AS外部的路由,仅通告给该区域。 |
虽然我们总是说成发送一个type-*的报文,但实际呢,我们回忆一下邻接关系的报文交互,LSA信息是通过LSU报文传递的。

其中,LSA的头部格式如下图所示:

需要关注的是以下三个字段,这三个字段唯一的标识一个LSA:
- 链路状态类型(Link-State Type):指示本条LSA的类型。
- 链路状态ID(Link-State ID):LSA的标识。不同类型的LSA对该字段的定义不同。
- 通告路由器(Advertising Router):产生该条LSA的路由器的router-id。
如果有两条LSA的这三个字段都一样,这表明这是同一条LSA,但他们肯定有新旧之分。而链路状态序列号、校验和、老化时间这三个字段就是为了判断LSA的“新鲜程度”。
接下来我们以下面这个网络拓扑为基础,详细的介绍每种LSA。请注意,我们要讲的是一个LSU报文中的数据内容里的LSA内的数据部分;也就是默认剥离了LSU的包头,LSA的头部。(有点绕口,在看一下上面的图理解一下。)
设定R3为area 0的DR。
type-1 LSA
报文格式

对于Router LSA,也就是type-1LSA,其LSA头部中的”链路状态类型“字段的值为1,”链路状态ID“字段的值为产生该LSA的路由器router-id。
除开LSA的头部信息,type-1 LSA包含的数据部分的内容(红框)如下:
**V 位(Virtual Link Endpoint Bit)**:如果该比特位被设置为 1,则表示该路由器为 Virtual Link(虚链路)的端点。
**E 位(External Bit)**:如果 E 比特位被设置为 1,则表示该路由器为 ASBR。 在 Stub区域中,不允许出现E比特位被设置为1的Type-1 LSA,因此Stub区域内不允许出现ASBR。
**B 位(Border Bit)**:如果 B 比特位被设置为 1,则表示该路由器为两个区域的边界路由器(即使该路由器为连接Area0),字母 B 意为 Border(边界)。
**链路数量(Links Number)**:该 Type-1 LSA 所描述的 Link(链路)数量。
我们已经知道每台路由器都会产生 Type-1 LSA,而且该 LSA 描述了路由器直连接口的状况和 Cost 值,实际上路由器正是采用包含在Type-1 LSA中的Link来描述直连接口的。
“链路数量”字段指明在该Type-1 LSA中,包含了几条Link。 每条Link均包含“链路类型”、 “链路ID” 、”链路数据”以及“度量值”这几个关键信息。 路由器可能会采用一个或者多个Link 来描述某个接口。
**链路类型(Link Type)**:本条 Link 的类型值,该值与 Link 的类型相关。 OSPF定义了多种链路类型,这些链路类型与接口的网络类型也是有关的。下表中罗列了 OSPF 定义的各种链路类型及对应的链路ID、链路数据的描述。
链路类型 描述 链路ID 链路数据 1 点对点协议的方式
连接到另一台路由器对端路由器的
router-id产生该LSA的接口IP地址 2 多路访问的方式(比如以太网)
连接到一个传输网络区域内DR的
接口IP地址产生该LSA的接口IP地址 3 连接到一个末梢网络
(该接口没有连接其他OSPF路由器)网络地址(网段) 子网掩码 4 虚链路 对端路由器的
router-id产生该LSA的接口IP地址 **链路ID(Link ID)**:Link 的标识,不同的链路类型,对链路 ID 值的定义是不同的。
**链路数据(Link Data)**:不同的链路类型对链路数据的定义是不同的。
**度量值(Metric)**:Cost 值。
TOS相关字段是ospf v1版本遗留下来的,为了做兼容,所以没有删除,目前已经不再使用了,因此可以忽略。(其他LSA内也有该字段,之后不再重复说明了)
举例说明
网络中的每台路由器都会产生type-1 LSA。
以R1为例:
其在GE0/0/0与GE0/0/1口启用了OSPF,因此它会产生一个用于描述这两个接口状况的type-1 LSA,并将该LSA泛洪到所在区域内。
接口GE0/0/0连接的是以太网,ip为192.168.123.1/24,该接口上有其他OSPF邻居(R2、R3)。因此描述该接口的关键信息为:链路类型=2,链路ID=192.168.123.3(R3为DR),链路数据=192.168.123.1,度量值=1(GE口表示千兆以太网)。
接口GE0/0/1连接的是以太网,ip为192.168.1.254/24,该接口上没有其他OSPF邻居,属于一个末梢网络。因此描述该接口的关键信息为:链路类型=3,链路ID=192.168.1.0,链路数据=255.255.255.0,度量值=1(GE口表示千兆以太网)。
使用 display ospf Isdb router 命令可以查看 LSDB 中的 Type-1 LSA。
如果在该命令后再增加 originate-router 关键字则可以查看指定的 OSPF 路由器(填入router-id)产生的 Type-1 LSA。
例如查看R1的type-1 LSA:
1 | [R1]dis ospf lsdb router originate-router 1.1.1.1 |
可以看到其中包含了两条link,信息就是我们前面分析过的。
以R3为例:
R3两个接口分别处于area0与area1,因为规定type-1 LSA只能在区域内传播,因此R3会产生两个type-1 LSA。
描述GE0/0/0接口的LSA在area0内传播,描述S1/0/0接口的LSA在area1内传播。
我们主要看area1的这个LSU报文,其中的LSA包含了两条link信息。
其中一条link的链路类型=1(表示点对点协议网络),链路ID=4.4.4.4(对端路由器id),链路数据=192.168.34.3(本端接口ip),度量值=48(华为的串口默认速率计算过来就是48)。
另一条link的链路类型=3,链路ID=192.168.34.0,链路数据=255.255.255.0,度量值=48。
之所以使用两条link信息来描述,是为了帮助其他路由器绘制网络拓扑:
第一条link用于告诉该串口对端设备的id与ip地址,第二条link是告诉该链路的网段是多少。
第一条只能说明ip地址,缺少掩码去推导网段。
而如果只使用第二条又不能告诉其他路由器这是点对点通信链路。
我们也查看一下R3的type-1 LSA详细信息:
1 | [R3]dis ospf lsdb router originate-router o 3.3.3.3 |
type-2 LSA
在type-1 LSA中,描述传输网络的链路类型的link信息内仅含有接口ip地址,并没有子网掩码,也因此不知道有多少路由器是在同一网段上。
因此就需要使用到type-2 LSA了。
OSPF的机制里,每个网段的路由器都会自行选举DR,未成为DR的路由器与DR构建邻接关系,并且邻居建立过程中的hello报文就包含了子网掩码的信息。因此对于DR来说,它清楚自己所处的网段以及与它相连的所有同网段路由器的接口ip地址与router-id。
所以,直接规定type-2 LSA由DR来产生并通告出去。
实际上,type-1的LSA也是经由DR来泛洪传播的。
R1的type-1LSA不会直接发给R2,而是发送给由身为DR的R3(使用224.0.0.6的组播地址);之后R3与R2再进行LSA的更新(使用224.0.0.5的组播地址)。
报文格式

在Type-2 LSA中,LSA头部中的“链路状态类型”字段的值为2,“链路状态ID”字段的值为产生这个Type-2 LSA的DR的接口ip地址。
除开LSA的头部信息,Type-2 LSA包含的数据部分的内容(红框)如下:
**网络掩码(Network Mask)**:该接口所连网络的网络掩码。
相连的路由器(Attached Router)的 Router-ID:连接到该网络的路由器的 Router-ID。
如果有多台路由器接入该网络,则使用多个字段描述。(至少包含了DR 自己的 Router-ID、以及与该 DR 建立了邻接关系的邻居的 Router-ID)
在OSPF中,因为使用的是组播地址,无法跨网段传输,所以每个网段都会选举DR。
因此仅需要在LSA头部信息里写明了该网段的DR的ip地址,再配合LSA数据部分的子网掩码,就可以得到网段了。
举例说明
我们先给之前的拓扑多加一台R5:192.168.15.5 /24 连接在R1右侧。
也就是说area0中存在了两个网段,而R1同时连接了这两个网段。
这次我们先直接查看LSDB表跟邻居表,以R1为视角:
在R1上输入display ospf peer 检查邻居信息。
1 | [R1]display ospf peer |
可以看到R1邻居信息中分了两块【Neighbors 】:
- 第一块里内容是R2与R3,其中DR: 192.168.123.3 BDR: 192.168.123.2。
- 第二块内容是R5,其中DR: 192.168.15.5 BDR: 192.168.15.1
查看type-2 LSA的命令为display ospf lsdb network
1 | [R1]display ospf lsdb network |
因为存在两个DR,所以有两条type-2 LSA。
以第一条为例:
Ls id : 192.168.123.3 —— 描述的该网段的DR的ip地址。
Net mask : 255.255.255.0 —— 描述该网段的子网掩码,配合上一条的ip地址即可得到网段地址。
Attached Router 3.3.3.3
Attached Router 1.1.1.1
Attached Router 2.2.2.2 —— 该网段内的ospf路由器的router-id。
得益于type-1与type-2 LSA在区域内泛洪,区域内的路由器LSDB表都是完全一致的,OSPF路由器就能够描绘一个区域内的完整拓扑,并发现各个网段,最终准确的计算出到达各个网段的最佳路径。
type-3 LSA
type-1与type-2解决了区域内的路由器计算,而要实现区域间路由的传递,就必须借助type-3 LSA。
type-3 LSA是为了解决区域间的路由问题,那么自然是由处于区域间的ABR来产生。
报文格式
不再用红框标注了,深色的为固定的LSA头部,浅色的为指定类型的LSA内容。
同样的,非必要不会在附上LSA的简述拓扑图,相信经过两个LSA的讲解,应该能理解怎么看LSDB表里LSA信息。
type-3 LSA是对区域内的type-1与type-2进行汇总归纳的LSA,其报文格式如下:

在Type-3 LSA中,”链路状态ID”字段的值为区域间路由的目的网络地址,其他字段及其含义如下。
- **网络掩码(Netmask)**:区域间路由的目的网络掩码。
- **度量值(Metric)**:路由的 Cost。
举例说明
以R3为例,检查其LSDB中的type-3 LSA:
命令:display ospf lsdb summary
1 | [R3]display ospf lsdb summary |
总结下来,R3往area0发送了一条type-3 LSA,用于描述area1里 R3-R4所处的网段。
R3往area1发送了4条type-3 LSA,用于描述area0里的4个网段。
值得注意的是,R3在发布type-3 LSA时,会附加上自己到达该网段的cost值(表中的“Tos 0 metric”字段)。
例如到达192.168.34.0是48,到达192.168.123.0是1,到达其他三个网段是2(需要经过两条千兆链路,1+1=2,交换机处不计算,因为对于ospf来说它感知不到经过了交换机以及经过了多少台交换机)
虽然说是多条LSA,但我们回顾一下LSU的报文格式。一条LSU报文内可以包含多条LSA,所以实际不等于路由器真的发了多条数据包。
![]()
基于type-1、type-2、type-3 LSA,一个OSPF网络内所有的路由器就都可以互相访问了。(只要配置符合ospf的规则)
type-3 LSA的防环机制
type-3 LSA内的信息,我们可以提取为ABR的router-id、目标网段、目标网段的掩码、cost值。对于收到该LSA的路由器来说,它能明白的就是前往该目标网段的下一跳是router-id为多少的路由器。
这么一说,你可能发现了,这和RIP协议非常相似——将自己路由表内的路由信息发送给邻居,下一跳会设置为自己。
因此,使用type-3 LSA是存在与RIP相似的“环路”隐患。
为此,ospf“借鉴”了RIP的“水平分割”——ABR只能将自己所连接的区域内路由通告给area0,而不能将从其他区域学习到路由再通告给area0。
type-4、type-5 LSA
我认为这两强相关的LSA放一起比较合适。
以新拓扑分析描述
让我们更新一下网络拓扑——让R4接入一个RIP网络中。(右上角)
显然,对于ospf网络中的路由器来说,它们并没有前往RIP网络的路由。
这时就需要R4将RIP的路由引入到ospf网络中,当我们在R4上执行引入路由的操作后,R4就认为自己是一台ASBR。
身为ASBR的R4会基于协议要求,会产生描述到达RIP网络的type-5 LSA。
该LSA经过路由器之间的LSU报文最终传遍ospf网络内的所有路由器,使得它们能知道前往RIP网络要经过R4。
但是对于area0区域的ospf路由器来说,它们仅拥有前往area1区域的type-3 LSA,而没有精准到达R4的LSA信息,因此它们还是无法路由到RIP网络。
对于R3来说,它与R4同属于area1,基于type-1 LSA,它清楚到达R4的路由。
因此ospf里规定了,同属一个区域的ABR(也就是R3),需要产生一条type-4 LSA,用于描述到达ASBR(也就是R4)的路由。
type-4 LSA会像type-5 LSA一样传遍所有路由器,结合起来,使其他路由器都能路由到RIP网络。
type-5 LSA
接下来我们就实际验证一下,首先我们在R4上进行路由引入,并检查type-5 LSA:
1 | [R4]ospf 1 |
RIP网络中192.168.78.0/24与192.168.47.0/24两个网段都描述出来了。
看的出来其报文格式应该就是:

对于Type-5 LSA, “链路状态ID”字段的值是外部路由的目的网络地址。其他主要字段的描述如下。
- 网络掩码(Netmask):外部路由的目的网络掩码。
- E 位:用于表示该外部路由使用的度量值类型。OSPF 定义了两种外部路由度量值类型,分别是 Metric-Type-1 和 Metric-Type-2。值为0表示Metric-Type-1,1表示Metric-Type-2。关于这两种度量值类型的区别,本文将在后续小节中阐述。
- 度量值(Metric):该外部路由的Cost。
- 转发地址(Forwarding Address, FA):当 FA 为 0.0.0.0 时,则到达该外部网段的流量会被发往引入这条外部路由的ASBR(即LSA头部的通告路由器)。而如果FA不为0.0.0.0,则流量会被发往这个转发地址。
- 外部路由标记(External Route Tag):这是一个只有外部路由才能够携带的标记,常被用于部署路由策略。
我们再抓个包看一下,都没直接抓过OSPF报文呢。这是在交换机处抓到的R3发送出来的OSPF报文:

这是一个OSPF报文,在这个OSPF报文中是LSU报文信息,LSU内包含了两条type-5 LSA。至于内容就不重复讲了。
type-4 LSA
在type-5 LSA内是描述了外部路由,以及发现该外部路由的路由器的router-id。
对于R1来说,它并不知道4.4.4.4这个router-id是谁——指示router-id的LSA是type-1 LSA,而type-1 LSA是不能跨区域的。
我们也可以直接使用display ospf peer命令查看R1的邻居表,也是找不到4.4.4.4的。
因此需要有人去发布type-4 LSA来告知area0区域内的路由器4.4.4.4这个路由器在哪。
我们在R1上去检查下type-4 LSA:
1 | [R1]display ospf lsdb asbr |
可以看到标识了4.4.4.4,以及发现者3.3.3.3。也就是说要去找4.4.4.4这个路由器,可以让3.3.3.3代劳。
我们也抓个包看看,这次我两个报文一起放出来,R3会发布两条OSPF报文,一条是通告type-5 LSA的,另一条是通告type-4 LSA的:

实际上type-4 LSA的报文结构就是type-3 LSA的结构,只不过链路状态ID填写为ASBR的router-id,且子网掩码字段的值填为0。
type-7 LSA
type-7 LSA是用于NSSA *(Not-So-Stubby Area,非完全末梢区域)*内的一种特殊LSA。
在stub区域内是禁止type-4与type-5 LSA的(包括自己本区域自主产生也是禁止的)。
如果想要仅拒绝其他区域传外部路由进入,但不妨碍自己本区域传外部路由出去,那么就可以配置该stub区域为NSSA。
在NSSA中,启用了type-7 LSA用于代替type -5 LSA。
也因此,作为代替品的type-7 LSA仅出现在NSSA中,该type-7 LSA在ABR处会被转化为type-5 LSA,再发布给其他区域。
同时,正因为是用于代替type-5 LSA的,所以type-7 LSA的报文格式与type-5 LSA一样,仅仅是链路类型从5改成了7。
再更新一遍拓扑,介绍type-7 LSA的原理
让我们最后一次修改一下拓扑——将RIP网络删除,改为R4下直连了一个网段192.168.4.0 /24,同时将area1配置为NSSA。

NSSA的配置需要在待修改区域的所有路由器上进行,因此在R3与R4配置如下命令:
1 | [R3]ospf 1 |
1 | [R4]ospf 1 |
现在,让我们在R4上配置引入外部路由(此处为直连路由):
1 | [R4-ospf-1-area-0.0.0.1]quit |
区域视图下是无法引入路由的,要退回到ospf进程视图下。
这时让我们看下刚刚在area1的串口链路上抓到的包:

LSA类型为7,链路状态ID为引入的192.168.4.0/24网段。(眼尖的会看到LSA数量为3,只是因为直接导入了直连路由,所以包括192.168.34.0/24也引入进去了)
再看一下R3发布到area0的LSA:

LSA类型为3,网段依旧是192.168.4.0/24,不过通告路由器改为了3.3.3.3。
基础配置命令与解决方案
基础配置
启用OSPF
执行命令system-view,进入系统视图。
执行命令ospf [ process-id | router-id router-id ] ,创建并进入OSPF进程视图。
第一个可选参数为进程id,默认为1。该进程id仅作用于本地,也就是说两台配置进同一个ospf网络的路由器可以进程名不一样。
第二个可选参数为手动配置router-id,默认使用本地上配置的最大的ip地址。手动配置Router ID时,必须保证任意两台路由器的router-id不相同。router-id也可以在创建ospf进程之前配置。
执行命令area area-id,进入OSPF区域视图。
执行命令network ip-address wildcard-mask,在OSPF区域中配置包含的网段,属于该网段的接口会自动启用OSPF功能。第二个参数配置的为通配符,而不是子网掩码。
通配符掩码中,0表示要检查的位,1表示不需要检查的位。如果不理解,可以当作是“反掩码”,比如通配符的0.0.0.255可以理解位子网掩码的255.255.255.0。
不过严谨来说,它并不是直接指示网络位与主机位的。举个例子,通配符可以写成0.0.0.254,这个通配符不仅表示了/24的子网,还可以筛选单数或者双数。(如果哪天发现了ip地址双数的能上网,单数的上不了网,记得去检查是不是哪里的通配符打错成254了)
”宣告“也只是指定设备上的什么接口开启ospf功能加入该进程该区域(接口的ip地址符合宣告的规则)。
如果计划宣告的接口不多,其实我们可以直接以 接口的ip地址 + 通配符0.0.0.0 来直接指定单个接口。
通配符0.0.0.0即表示严格匹配前者,而前者填写为接口的ip地址,即为直接指定该接口。
引入外部路由
- 执行命令system-view,进入系统视图。
- 执行命令ospf,进入OSPF进程视图。
- 执行命令import-route { bgp [ permit-ibgp ] | direct | unr | rip [ process-id-rip ] | static | isis [ process-id-isis ] | ospf [ process-id-ospf ] } [ cost cost | type type | tag tag | route-policy route-policy-name ],引入其它协议的路由信息。
- [ cost cost | type type | tag tag | route-policy route-policy-name ] 这一段是可选对引入的外部路由进行一些自定义——cost值,类型,标记,路由策略。
检查配置
- 在任意视图下执行display ospf [ process-id ] peer命令,查看指定OSPF进程的邻居信息。
- 在任意视图下执行display ospf [ process-id ] interface命令,查看指定OSPF进程的接口信息。
- 在任意视图下执行display ospf [ process-id ] routing命令,查看指定OSPF进程的路由表信息。
- 在任意视图下执行display ospf [ process-id ] lsdb命令,查看指定OSPF进程的LSDB信息。
路由汇总与默认路由
路由汇总
ABR向其它区域发送路由信息时,以网段为单位生成Type3 LSA。
当区域中存在连续的网段(具有相同前缀的路由信息)时,可以通过abr-summary命令将这些网段聚合成一个网段。
ABR向其他区域只发送一条聚合后的LSA(对于自己本身依旧保持原有的LSA),所有指定的聚合网段范围的LSA将不会再被单独发送。
从而有效减少路由表中的条目,减小对系统资源的占用,不影响系统的性能。
配置ABR路由聚合
- 执行命令system-view,进入系统视图。
- 执行命令ospf [ process-id ],进入OSPF进程视图。
- 执行命令area area-id,进入OSPF区域视图。
- 执行命令abr-summary ip-address mask [ cost { cost | inherit-minimum } ] ,配置OSPF的ABR路由聚合。
配置ASBR路由聚合
- 执行命令system-view,进入系统视图。
- 执行命令ospf [ process-id ],进入OSPF进程视图。
- 执行命令asbr-summary ip-address mask [ cost cost | tag tag ] ,配置OSPF的ASBR路由聚合。
默认路由
为了减少路由表的容量,还可以配置引入默认路由,保证网络的高可用性。
配置OSPF将默认路由通告到OSPF路由区域
执行命令system-view,进入系统视图。
执行命令ospf [ process-id ],进入OSPF进程视图。
执行命令default-route-advertise [ [ always | permit-calculate-other ] | cost cost | type type | route-policy route-policy-name [ match-any ] ] ,将默认路由通告到OSPF路由区域。
always表示无论本机是否存在激活的非本OSPF进程的默认路由,都会产生并发布一个描述默认路由的LSA。
permit-calculate-other表示在发布默认路由后,仍允许计算其他路由器发布的默认路由。
虚链路(Virtual link)
OSPF里规定了所有区域都必须与骨干区域area0相连,否则LSA的泛洪就会出现问题,非直连区域会成为“孤岛”。
一般来说,我们都是要区域重新划分,保证区域直连area0。
但现网中,有的时候条件并不允许,无法重新规划为直连area0。
这时就可以考虑一种临时方案——虚链路。
虚链路是指在逻辑上虚拟出一条链路,使得该链路两台的设备能直接通信,直接尝试构建邻接关系。
而虚链路本身是承载在先有物理链路上的,我们可以理解为套娃、套壳。
使用虚链路让区域内一台路由器“直连”到area0里,该路由器则作为ABR负责该区域的LSA汇总。
操作步骤
执行命令system-view,进入系统视图。
执行命令ospf [ process-id ],进入OSPF进程视图。
执行命令area area-id,进入OSPF区域视图。
执行命令vlink-peer router-id [ smart-discover | hello hello-interval | retransmit retransmit-interval | trans-delay trans-delay-interval | dead dead-interval | [ simple [ plain plain-text | [ cipher ] cipher-text ] | { md5 | hmac-md5 | hmac-sha256 } [ key-id { plain plain-text | [ cipher ] cipher-text } ] | authentication-null | keychain keychain-name ] ] ,创建到达指定路由器的虚连接。
在另一端的路由器上也需要配置此命令。
注意事项
OSPF邻居建立不起来?
以下各项的答案为“是”,才是正常的。
实际本质就是两端的hello报文能互相发送给对方,并且hello报文内信息除了标识router-id要不同以外,其他的信息需要一样。
检查邻居两端的接口物理和协议状态是否UP,状态是否稳定,接口是否不丢包,两边互ping大包是否能通。
若物理接口不Up或是不稳定(有振荡现象),请排查物理链路和链路层协议,确保物理和协议状态都是Up,并且接口无错误计数。
可以通过ping测试,长ping测试是否存在丢包现象,ping大包(1500字节以上)测试是否存在大包不通的现象。
检查链路两端OSPF进程的Router ID是否唯一。
分别在链路两端的设备上执行命令display ospf [ process-id ] brief,查看OSPF进程的Router ID。
RouterID尽量保证全网唯一,否则有可能邻居不能正常建立、路由信息不正确的问题。建议在设备上单独为每个OSPF进程配置全网唯一的Router ID。
如果链路两端OSPF进程的Router ID冲突,请在系统视图下执行命令ospf [ process-id ] router-id router-id,修改OSPF进程的Router ID以保证不冲突。
修改OSPF进程的Router ID之后,必须在用户视图下执行命令reset ospf[ process-id ] process重启进程后,新配置的Router ID才会生效。
检查链路两端OSPF区域ID是否一致。
分别在链路两端的设备上执行命令display ospf [ process-id ] brief,查看OSPF的区域ID。
如果链路两端的OSPF区域ID不一致,请在OSPF视图下执行命令area area-id,修改OSPF区域ID以保证一致。
检查链接两端OSPF接口的网络类型是否一致。
分别在链路两端的设备上执行命令display ospf [ process-id ] interface,查看OSPF接口的接口类型。
一般情况下,链路两端的OSPF接口的网络类型必须一致,否则双方不能正常建立起OSPF邻居关系。
- 当链路两端的OSPF接口的网络类型一端是广播网(以太网)而另一端是P2P时,双方仍可以正常的建立起邻居关系,但互相学不到路由信息。
- 当链路两端的OSPF接口的网络类型一端是P2MP而另一端是P2P时,双方仍可以正常的建立起邻居关系,但互相学不到路由信息。为了相互学到路由信息,此时需要在链路两端的OSPF接口上配置相同的Hello报文发送间隔和邻居失效时间。
如果OSPF接口的网络类型不一致,请在运行OSPF协议的接口视图下执行命令ospf network-type { broadcast | nbma | p2mp | p2p },修改OSPF接口的网络类型以保证一致。
如果链路两端OSPF接口的网络类型都是NBMA,则必须在OSPF视图下执行命令peer ip-address [ dr-priority priority ],配置NBMA网络的OSPF邻居。
检查链路两端OSPF接口的IP地址的掩码是否一致。
分别在链路两端的设备上执行命令display current-configuration interface interface-type interface-number,查看OSPF接口的IP地址。
一般情况下,链路两端的OSPF接口的IP地址的掩码必须一致,否则双方不能正常建立OSPF邻居关系。
但在P2MP网络中,可以通过在运行OSPF协议的接口视图下配置命令ospf p2mp-mask-ignore来使设备忽略对网络掩码的检查,从而正常建立OSPF邻居关系。
如果OSPF接口的IP地址的掩码不一致,请在运行OSPF协议的接口视图下执行命令ip address ip-address { mask | mask-length },修改OSPF接口的IP地址以保证掩码一致。
检查链路两端OSPF接口的IP地址所在网段是否包含在区域内配置的network内。
也就是检查接口是否激活了OSPF。
分别在链路两端的设备上执行命令display current-configuration interface interface-type interface-number,查看OSPF接口的IP地址;执行命令display current-configuration configuration ospf,查看OSPF进程的配置。
满足下面两个条件,OSPF协议才能在接口上运行:
- 接口的IP地址掩码长度≥network命令中的掩码长度。OSPF使用反掩码,例如0.0.0.255表示掩码长度24位。
- 接口的主IP地址必须在network命令指定的网段范围之内。
如果检查发现接口IP地址与配置的network不满足上述条件,请在运行OSPF协议的接口视图下执行命令ip address ip-address { mask | mask-length },修改接口的IP地址;或者在OSPF进程对应的区域视图下执行命令network,修改配置的网段,保证满足上述条件。
检查链路两端OSPF接口的DR优先级是否非零。
分别在链路两端的设备上执行命令display ospf [ process-id ] interface,查看OSPF接口的DR优先级。
对于广播和NBMA类型网络,链路中至少要有一个OSPF接口的DR优先级不为0,这样才能正常选举出DR。否则两边的邻居状态只能达到2-Way。
如果链路两端OSPF接口的DR优先级都为0,请在运行OSPF协议的接口视图下执行命令ospf dr-priority priority,修改OSPF接口的DR优先级以保证至少有一个接口的DR优先级不为0。
报文认证
为了避免有攻击者通过接入非法路由器并启用OSPF,向我方OSPF网络中注入大量无用的LSA,可以在OSPF中配置报文认证。
OSPF 支持三种类型的认证方式,分别是空认证(Null Authentication)、简单口令认证(Simple Password)、密文认证(Ctyptograhpic Authentication),这三种认 证方式对应的“认证类型”字段值分别为0、1和2。
空认证:
- 空认证即不做认证,这是OSPF接口的默认设置。
简单口令认证:
简单口令认证又称明文认证,OSPF报文的认证数据字段中会填写为配置的明文口令(密码),接口收到该OSPF报文就会去检查包含的口令是否正确。
但因为此种认证是采用明文的方式,存在被截获口令的隐患,并不安全。
密文认证:
- 密文认证是对口令进行了加密,报文中传输的是加密后的口令。(虽然加密对安全性没有太多的帮助,依旧可以截获并使用报文中的口令,只是无法得知加密前的口令是什么)
- 密文认证还增加了密码序列号这一字段以预防重放攻击(截获正常报文,重复发送)
命令不作介绍了,有兴趣可以查看文档,在模拟器上测试一轮。
结语
OSPF还有其他非常多的配置命令,碍于篇幅,以及一般都不会使用的原因,本文不做介绍。
感兴趣的可以查看产品手册参考可配置命令,其中大多数都是进行优先的命令。但实际现网中,能通就行,真有次优路由也无妨
另外,本文弱化了网络类型的概念,OSPF可以在多种网络类型中使用,但个人认为其他网络类型目前使用场景太少了,现在是以太网一统天下的时代,因此本文是默认为以太网环境下进行介绍的。
此外,本文还是默认为ipv4环境,使用的是OSPF Version 2。OSPF还有一个OSPF Version 3,是针对ipv6场景的,有机会的话我们再介绍。